package com.itcam.interview.pro00.thread;

import java.util.concurrent.CountDownLatch;

/**
 * @author : Cammy.Wu
 * Description : 
 */

public class CountDownLatchExample {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(3);

        Thread thread1 = new Thread(() -> {
            try {
                Thread.sleep(1000);
                System.out.println("线程1完成任务");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                latch.countDown();
            }
        });

        Thread thread2 = new Thread(() -> {
            try {
                Thread.sleep(1000);
                System.out.println("线程2完成任务");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                latch.countDown();
            }
        });

        Thread thread3 = new Thread(() -> {
            try {
                Thread.sleep(1000);
                System.out.println("线程3完成任务");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                latch.countDown();
            }
        });

        Thread thread4 = new Thread(() -> {
            try {
                Thread.sleep(1000);
                System.out.println("线程4完成任务");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                latch.countDown();
            }
        });

        Thread thread5 = new Thread(() -> {
            try {
                Thread.sleep(1000);
                System.out.println("线程5完成任务");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                latch.countDown();
            }
        });

        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();
        thread5.start();


        /*
            为什么计数器为 0 没有报错
                   countDown() 方法：当计数器已经为 0 时，再次调用 countDown() 方法不会报错，也不会对计数器的值产生影响。
                 因为 countDown() 方法内部会检查计数器是否已经为 0，如果是，则不会进行任何操作。
                   await() 方法：当计数器为 0 时，调用 await() 方法会立即返回，不会阻塞线程。这是因为 await() 方法的设计
                 目的就是等待计数器降为 0，一旦计数器为 0，等待的条件就满足了，线程可以继续执行。
                   综上所述，CountDownLatch 设计为在计数器为 0 时不会报错，而是正常执行后续操作，这符合其作为同步工具的设计
                 初衷。如果你希望在计数器为 0 后进行其他操作，可以在 await() 方法之后添加相应的代码。
         */

        // 主线程等待，直到计数器归零
        latch.await();
        System.out.println("所有子线程任务完成，主线程继续执行");
        System.out.println(latch.getCount());
    }
}
